From b20c6dc5f87b4051433925db7963bc7d530635f5 Mon Sep 17 00:00:00 2001 From: oliskoli Date: Mon, 19 Dec 2005 22:44:15 +0000 Subject: [PATCH] Enhance geoniche to read the "real" geoniche binary format. git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@1660 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/geoniche.c | 225 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 209 insertions(+), 16 deletions(-) diff --git a/gpsbabel/geoniche.c b/gpsbabel/geoniche.c index 190c96ecb..4bc249316 100644 --- a/gpsbabel/geoniche.c +++ b/gpsbabel/geoniche.c @@ -22,11 +22,18 @@ #include "defs.h" #include "coldsync/palm.h" #include "coldsync/pdb.h" +#include "garmin_tables.h" + +#include +#include #define MYNAME "Geoniche" -#define MYTYPE 0x50454e44 /* PEND */ +#define MYTYPE_ASC 0x50454e44 /* PEND */ +#define MYTYPE_BIN 0x44415441 /* DATA */ #define MYCREATOR 0x47656f4e /* GeoN */ +#undef GEONICHE_DBG + static FILE *FileIn; static FILE *FileOut; static const char *FilenameOut; @@ -180,17 +187,10 @@ eof: } static void -data_read(void) +geoniche_read_asc(const struct pdb *pdb) { - struct pdb *pdb; struct pdb_record *pdb_rec; - if (NULL == (pdb = pdb_Read(fileno(FileIn)))) - fatal(MYNAME ": pdb_Read failed\n"); - - if ((pdb->creator != MYCREATOR) || (pdb->type != MYTYPE)) - fatal(MYNAME ": Not a GeoNiche file.\n"); - /* Process record 0 */ pdb_rec = pdb->rec_index.rec; if (strcmp((char *) pdb_rec->data, Rec0Magic)) @@ -326,7 +326,9 @@ data_read(void) tm.tm_mon -= 1; tm.tm_year -= 1900; sscanf(timestr, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - wpt->creation_time = mktime(&tm); + if (tm.tm_year >= 1970) { + wpt->creation_time = mktime(&tm); + } xfree(datestr); xfree(timestr); @@ -352,6 +354,186 @@ data_read(void) waypt_add(wpt); } +} + +static char *geoniche_icon_map[] = /* MPS */ +{ + /* 21 */ "Cross", + /* 22 */ "Cross (light)", + /* 23 */ "Cross (little)", + /* 24 */ "Cross (straight)", + /* 25 */ "Cross (light straight)", + /* 26 */ "Cross (little straight)", + /* 27 */ NULL, + /* 28 */ NULL, + /* 29 */ NULL, + /* 2A */ "Flag", + /* 2B */ "Car", /* 56 */ + /* 2C */ "Gas Station", /* 8 */ + /* 2D */ "Observation Point", + /* 2E */ "Scenic Area", /* 48 */ + /* 2F */ "City", + /* 30 */ "Mountains", + /* 31 */ "Park", /* 46 */ + /* 32 */ "Forest", /* 105 */ + /* 33 */ "Campground", /* 38 */ + /* 34 */ NULL, + /* 35 */ "Men", + /* 36 */ "Woman", + /* 37 */ "Hotel", /* 59 */ + /* 38 */ "Residence", /* 10 */ + /* 39 */ "Restaurant", /* 11 */ + /* 3A */ "Cafe", + /* 3B */ NULL, + /* 3C */ "Airport", /* 107 */ + /* 3D */ "Medical Facility", /* 43 */ + /* 3E */ "Ropeway", + /* 3F */ "Sailing Area", + /* 40 */ "Anchor", + /* 41 */ NULL, /* Half Anchor ??? */ + /* 42 */ "Fishing Area", /* 7 */ + /* 43 */ "Stop Sign", + /* 44 */ "Question Sign", + /* 45 */ NULL, + /* 46 */ NULL, + /* 47 */ "Euro Sign", + /* 48 */ "Bank", /* 6 */ + /* 49 */ NULL, + /* 4A */ "Left Arrow", + /* 4B */ "Right Arrow", + /* 4C */ "Traditional Cache", + /* 4D */ "Multi-Cache", /* 86 */ + /* 4E */ "Virtual Cache", /* 48 */ + /* 4F */ "Letterbox Cache", + /* 50 */ "Event Cache", /* 47 */ + /* 51 */ "Webcam Cache", /* 90 */ + /* 52 */ "Mystery or puzzle Cache", +}; + +static char * +geoniche_icon_to_descr(const int no) +{ + char *result = NULL; + + if (no >= 0x21) + { + int i = no - 0x21; + if (i <= 49) + { + result = geoniche_icon_map[i]; + } + } + if (result != NULL) + { + result = xstrdup(result); + } + return result; +} + +static void +geoniche_read_bin(const struct pdb *pdb) +{ + struct pdb_record *pdb_rec; + int ct = 0; + waypoint *waypt; + + /* Process records */ + + for (pdb_rec = pdb->rec_index.rec; pdb_rec != NULL; pdb_rec = pdb_rec->next) + { + char *vdata = (char *) pdb_rec->data; + int vlen = pdb_rec->data_len; + struct tm created, visited; + int i, icon_nr, selected; + int latdeg, londeg; + double lat, lon, altitude; + waypoint *waypt; + + memset(&visited, 0, sizeof(visited)); + memset(&created, 0, sizeof(created)); + + latdeg = be_read16(vdata + 0); + lat = be_read32(vdata + 2); + londeg = be_read16(vdata + 6); + lon = be_read32(vdata + 8); + altitude = (float) be_read32(vdata + 12); + selected = vdata[16]; + created.tm_min = be_read16(vdata + 20); + created.tm_hour = be_read16(vdata + 22); + created.tm_mday = be_read16(vdata + 24); + created.tm_mon = be_read16(vdata + 26); + created.tm_year = be_read16(vdata + 28); + visited.tm_min = be_read16(vdata + 34); + visited.tm_hour = be_read16(vdata + 36); + visited.tm_mday = be_read16(vdata + 38); + visited.tm_mon = be_read16(vdata + 40); + visited.tm_year = be_read16(vdata + 42); + +#ifdef GEONICHE_DBG + printf(MYNAME "-date: %04d/%02d/%02d, %02d:%02d (%04d/%02d/%02d, %02d:%02d)\n", + created.tm_year, created.tm_mon, created.tm_mday, created.tm_hour, created.tm_min, + visited.tm_year, visited.tm_mon, visited.tm_mday, visited.tm_hour, visited.tm_min); +#endif + icon_nr = vdata[62]; + + latdeg = 89 - latdeg; + lat = lat * (double) 0.0000006; + if (latdeg >= 0) + lat = (double) 60.0 - lat; + else + latdeg++; + + lon = lon * (double) 0.0000006; + while (londeg >= 360) londeg-=360; + if (londeg > 180) + { + lon = (double) 60.0 - lon; + londeg = londeg - 359; + } + + created.tm_year-=1900; + created.tm_mon--; + + waypt = waypt_new(); + + waypt->shortname = xstrdup(vdata + 63); + waypt->altitude = altitude; + waypt->creation_time = mkgmtime(&created); + + GPS_Math_DegMin_To_Deg(latdeg, lat, &waypt->latitude); + GPS_Math_DegMin_To_Deg(londeg, lon, &waypt->longitude); + + waypt->icon_descr = geoniche_icon_to_descr(icon_nr); + if (waypt->icon_descr != NULL) + waypt->wpt_flags.icon_descr_is_dynamic = 1; + + waypt_add(waypt); + } +} + +static void +data_read(void) +{ + struct pdb *pdb; + + if (NULL == (pdb = pdb_Read(fileno(FileIn)))) + fatal(MYNAME ": pdb_Read failed\n"); + + if (pdb->creator != MYCREATOR) + fatal(MYNAME ": Not a GeoNiche file.\n"); + + switch(pdb->type) + { + case MYTYPE_ASC: + geoniche_read_asc(pdb); + break; + case MYTYPE_BIN: + geoniche_read_bin(pdb); + break; + default: + fatal(MYNAME ": Unsupported GeoNiche file.\n"); + } + free_pdb(pdb); } @@ -415,6 +597,7 @@ copilot_writewpt(const waypoint *wpt) char timestr[8+1]; char *notes; int id; + time_t tx; if (ct == 0) { @@ -434,9 +617,16 @@ copilot_writewpt(const waypoint *wpt) if (id < 0) id = ct; - tm = *localtime(&wpt->creation_time); - strftime(datestr, sizeof(datestr), "%m/%d/%Y", &tm); - strftime(timestr, sizeof(timestr), "%H:%M:%S", &tm); + tx = (wpt->creation_time != 0) ? wpt->creation_time : gpsbabel_time; + if (tx == 0) { /* maybe zero during testo (freezed time) */ + strcpy(datestr, "01/01/1904"); /* this seems to be the uninitialized date value for geoniche */ + strcpy(timestr, "00:00:00"); + } + else { + tm = *localtime(&tx); + strftime(datestr, sizeof(datestr), "%m/%d/%Y", &tm); + strftime(timestr, sizeof(timestr), "%H:%M:%S", &tm); + } /* Notes field MUST have soemthing in it */ if (!wpt->notes || wpt->notes[0] == 0) @@ -502,15 +692,18 @@ data_write(void) if (NULL == (PdbOut = new_pdb())) fatal (MYNAME ": new_pdb failed\n"); - if (Arg_dbname) + if (Arg_dbname) { + if (case_ignore_strcmp(Arg_dbname, "GeoNiche Targets") == 0) + fatal(MYNAME ": Reserved database name!\n"); strncpy(PdbOut->name, Arg_dbname, PDB_DBNAMELEN); + } else strncpy(PdbOut->name, FilenameOut, PDB_DBNAMELEN); PdbOut->name[PDB_DBNAMELEN-1] = 0; PdbOut->attributes = PDB_ATTR_BACKUP; PdbOut->ctime = PdbOut->mtime = current_time() + (49*365 + 17*366) * (60*60*24); - PdbOut->type = MYTYPE; + PdbOut->type = MYTYPE_ASC; PdbOut->creator = MYCREATOR; PdbOut->version = 0; PdbOut->modnum = 1; @@ -535,5 +728,5 @@ ff_vecs_t geoniche_vecs = data_write, NULL, Args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; -- 2.30.2